﻿using DGIS.Service.IService.IDataService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DGIS.Service.Enum;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using DGIS.Service.Model;

namespace DGIS.Service.Service.DataService
{
    public class DataOpenService : IDataOpenService
    {
        public IFeatureLayer OpenFromGDB(string gdbPath, string layerName)
        {
            IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass();
            IWorkspace workspace = workspaceFactory.OpenFromFile(gdbPath, 0);

            IFeatureClass featureClass = GetFeatureClass(workspace, layerName);

            return CreateFeatureLayer(featureClass, layerName);
        }

        public IFeatureLayer OpenFromMDB(string mdbPath, string layerName)
        {
            IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
            IWorkspace workspace = workspaceFactory.OpenFromFile(mdbPath, 0);

            IFeatureClass featureClass = GetFeatureClass(workspace, layerName);

            return CreateFeatureLayer(featureClass, layerName);
        }

        public IFeatureLayer OpenFromSDE(string server, string userName, string psw, string dataBaseName, SDETypeEnum sdeType, string layerName)
        {
            // 用连接属性创建 propertySet 
            string instance = "sde:SQLServer:";
            switch (sdeType)
            {
                case SDETypeEnum.Oracle:
                    instance = "sde:oracle11g:";
                    break;
                case SDETypeEnum.SQLServer:
                    instance = "sde:SQLServer:";
                    break;
                case SDETypeEnum.PostgreSQL:
                    instance = "sde:postgresql:";
                    break;
                default:
                    break;
            }

            IPropertySet propertySet = new PropertySetClass();
            propertySet.SetProperty("SERVER", server);
            propertySet.SetProperty("INSTANCE", instance);
            propertySet.SetProperty("USER", userName);
            propertySet.SetProperty("PASSWORD", psw);
            propertySet.SetProperty("VERSION", "SDE.DEFAULT");
            //propertySet.SetProperty("AUTHENTICATION_MODE", "DBMS");
            propertySet.SetProperty("DATABASE", dataBaseName);

            SdeWorkspaceFactory sdeWorkspaceFactory = new SdeWorkspaceFactoryClass();
            IWorkspace workspace = sdeWorkspaceFactory.Open(propertySet, 0);

            IFeatureClass featureClass = GetFeatureClass(workspace, layerName);

            return CreateFeatureLayer(featureClass, layerName);
        }

        public IFeatureLayer OpenFromShp(string shpPath)
        {
            string folder = System.IO.Path.GetDirectoryName(shpPath);
            string name = System.IO.Path.GetFileNameWithoutExtension(shpPath);

            IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactory();
            IWorkspace workspace = workspaceFactory.OpenFromFile(folder, 0);

            IFeatureClass featureClass = GetFeatureClass(workspace, name);

            return CreateFeatureLayer(featureClass, name);
        }

        private IFeatureClass GetFeatureClass(IWorkspace workspace, string featureClassName)
        {
            IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(featureClassName);

            return featureClass;
        }

        private IFeatureLayer CreateFeatureLayer(IFeatureClass featureClass, string layerName)
        {
            return new FeatureLayerClass()
            {
                FeatureClass = featureClass,
                Name = layerName
            };
        }

        public List<DataLayer> GetLayerList(string dbPath, WorkspaceTypeEnum type, out IWorkspace workspace)
        {
            List<DataLayer> items = new List<DataLayer>();

            IWorkspaceFactory workspaceFactory = null;
            switch (type)
            {
                case WorkspaceTypeEnum.Mdb:
                    workspaceFactory = new AccessWorkspaceFactoryClass();
                    break;
                case WorkspaceTypeEnum.GeoDatabase:
                    workspaceFactory = new FileGDBWorkspaceFactoryClass();
                    break;
                default:
                    break;
            }

            try
            {
                workspace = workspaceFactory.OpenFromFile(dbPath, 0);
            }
            catch (Exception)
            {
                workspace = null;
                return items;
            }            

            //获取图层
            IEnumDataset dataSets = workspace.get_Datasets(esriDatasetType.esriDTAny);
            IDataset dataSet = dataSets.Next();

            while (dataSet != null)
            {
                DataLayer item = new DataLayer()
                {
                    Name = dataSet.Name
                };

                if (dataSet.Type == esriDatasetType.esriDTFeatureClass)
                {
                    item.LayerType = LayerTypeEnum.FeatureLayer;
                }
                else if (dataSet.Type == esriDatasetType.esriDTRasterDataset)
                {
                    item.LayerType = LayerTypeEnum.RasterLayer;
                }
                else if (dataSet.Type == esriDatasetType.esriDTFeatureDataset)
                {
                    item.LayerType = LayerTypeEnum.dataSet;
                    item.Child = GetDatasetLayers(dataSet);
                }
                items.Add(item);

                dataSet = dataSets.Next();
            }

            return items;
        }
        
        public List<DataLayer> GetLayerList(string server, string userName, string psw, string dataBaseName, SDETypeEnum sdeType, out IWorkspace workSpace)
        {
            List<DataLayer> items = new List<DataLayer>();

            // 用连接属性创建 propertySet 
            string instance = "sde:SQLServer:";
            switch (sdeType)
            {
                case SDETypeEnum.Oracle:
                    instance = "sde:oracle11g:";
                    break;
                case SDETypeEnum.SQLServer:
                    instance = "sde:SQLServer:";
                    break;
                case SDETypeEnum.PostgreSQL:
                    instance = "sde:postgresql:";
                    break;
                default:
                    break;
            }

            IPropertySet propertySet = new PropertySetClass();
            propertySet.SetProperty("SERVER", server);
            propertySet.SetProperty("INSTANCE", instance+server);
            propertySet.SetProperty("USER", userName);
            propertySet.SetProperty("PASSWORD", psw);
            propertySet.SetProperty("VERSION", "SDE.DEFAULT");
            //propertySet.SetProperty("AUTHENTICATION_MODE", "DBMS");
            propertySet.SetProperty("DATABASE", dataBaseName);

            SdeWorkspaceFactory sdeWorkspaceFactory = new SdeWorkspaceFactoryClass();
            try
            {
                workSpace = sdeWorkspaceFactory.Open(propertySet, 0);
            }
            catch (Exception)
            {
                workSpace = null;
                return items;
            }

            //获取图层
            IEnumDataset dataSets = workSpace.get_Datasets(esriDatasetType.esriDTAny);
            IDataset dataSet = dataSets.Next();

            while (dataSet != null)
            {
                DataLayer item = new DataLayer()
                {
                    Name = dataSet.Name
                };

                if (dataSet.Type == esriDatasetType.esriDTFeatureClass)
                {
                    item.LayerType = LayerTypeEnum.FeatureLayer;
                }
                else if (dataSet.Type == esriDatasetType.esriDTRasterDataset)
                {
                    item.LayerType = LayerTypeEnum.RasterLayer;
                }
                else if (dataSet.Type == esriDatasetType.esriDTFeatureDataset)
                {
                    item.LayerType = LayerTypeEnum.dataSet;
                    item.Child = GetDatasetLayers(dataSet);
                }
                items.Add(item);

                dataSet = dataSets.Next();
            }

            return items;
        }

        /// <summary>
        /// 递归获取图层列表
        /// </summary>
        /// <param name="dataset"></param>
        /// <returns></returns>
        private List<DataLayer> GetDatasetLayers(IDataset dataset)
        {
            List<DataLayer> items = new List<DataLayer>();

            IEnumDataset pDataSets = dataset.Subsets;
            if (pDataSets != null)
            {
                IDataset pDataSet = pDataSets.Next();
                while (pDataSet != null)
                {
                    DataLayer item = new DataLayer()
                    {
                        Name = pDataSet.Name
                    };

                    if (pDataSet.Type == esriDatasetType.esriDTFeatureClass)
                    {
                        item.LayerType = LayerTypeEnum.FeatureLayer;
                    }
                    else if (pDataSet.Type == esriDatasetType.esriDTRasterDataset)
                    {
                        item.LayerType = LayerTypeEnum.RasterLayer;
                    }
                    else if (pDataSet.Type == esriDatasetType.esriDTFeatureDataset)
                    {
                        item.LayerType = LayerTypeEnum.dataSet;
                        item.Child = GetDatasetLayers(pDataSet);
                    }
                    items.Add(item);

                    pDataSet = pDataSets.Next();
                }
            }

            return items;
        }
    }
}
